package pt.elvis.revanweb.client;

import java.util.ArrayList;
import java.util.List;

import pt.elvis.revanweb.client.CustomEvents.AdminClickEvent;
import pt.elvis.revanweb.client.CustomEvents.AdminClickEventHandler;
import pt.elvis.revanweb.client.CustomEvents.AppUtils;
import pt.elvis.revanweb.client.CustomEvents.AuthenticationEvent;
import pt.elvis.revanweb.client.CustomEvents.AuthenticationEventHandler;
import pt.elvis.revanweb.client.CustomEvents.BookmarkClickEvent;
import pt.elvis.revanweb.client.CustomEvents.BookmarkClickEventHandler;
import pt.elvis.revanweb.client.DatabaseObjects.Bookmarks_Objects;
import pt.elvis.revanweb.client.DatabaseObjects.DatabaseHelper;
import pt.elvis.revanweb.client.DatabaseObjects.MyRequestCallback;
import pt.elvis.revanweb.client.DatabaseObjects.User_data;
import pt.elvis.revanweb.client.uiBinders.AdminPanel;
import pt.elvis.revanweb.client.uiBinders.BookmarksPanel;
import pt.elvis.revanweb.client.uiBinders.HeaderPanel;
import pt.elvis.revanweb.client.uiBinders.LeftMenu;
import pt.elvis.revanweb.client.uiBinders.LoginPanel;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;

/**
 * 
 * Entry point classes define <code>onModuleLoad()</code>.
 * 
 */
public class RevanWeb implements EntryPoint {
	private RootLayoutPanel rootLayout;
	private LeftMenu leftMenu = new LeftMenu();
	private DockLayoutPanel dock = new DockLayoutPanel(Unit.EM);
	private BookmarksPanel bookmarksPanel;
	/*
	 * This list holds all the bookmarks. It's static so it can accessed by any
	 * class in any part of the project.
	 */
	// TODO: Change this behaviour. Declare the object on other classes, and
	// point it to this list.
	public static List<Bookmarks_Objects> bookmarksList = new ArrayList<Bookmarks_Objects>();
	public static List<ImageAnchor> imageAnchorList = new ArrayList<ImageAnchor>();
	public static boolean isLoaded;
	public static boolean reloadBookmarks = false;
	private User_data loggedUser;
	private AdminPanel adminPanel;
	private HeaderPanel header = new HeaderPanel();
	private SimplePanel scrollPanel = new SimplePanel();

	/**
	 * Where the code starts it's execution.
	 * 
	 * @author elvis
	 */
	public void onModuleLoad() {
		dock.setStylePrimaryName("contentPanel");
		final LoginPanel loginPanel = new LoginPanel();
		// Check if user is already logged in.
		DatabaseHelper.getData_GET("is_logged.php", new MyRequestCallback() {

			@Override
			protected void onText(String text) {
				User_data userData = parseUserData(text);
				if (userData == null) {
					RootPanel.get("wrapper").add(loginPanel);
					RootPanel.get("wrapper").getElement().getStyle()
							.setPosition(Position.RELATIVE);
				} else {
					AuthenticationEvent auth = new AuthenticationEvent();
					auth.setUser(userData);
					AppUtils.EVENT_BUS.fireEvent(auth);
				}
			}
		});

		// The authentication handler. This event fires from LoginPanel.java.
		AppUtils.EVENT_BUS.addHandler(AuthenticationEvent.TYPE,
				new AuthenticationEventHandler() {
					@Override
					public void onAuthenticationChanged(
							AuthenticationEvent authenticationEvent) {
						loggedUser = authenticationEvent.getUser();
						bookmarksPanel = new BookmarksPanel(loggedUser
								.getSESSION_ID());
						adminPanel = new AdminPanel(loggedUser.getSESSION_ID());
						adminPanel.loadEditTableInstance();

						loginPanel.setVisible(false);
						RootPanel.get("wrapper").clear();
						dock.addNorth(header, 3);
						dock.addWest(leftMenu, 10);
						dock.add(scrollPanel);
						scrollPanel.clear();
						scrollPanel.add(bookmarksPanel);
						rootLayout = RootLayoutPanel.get();
						rootLayout.add(dock);
					}
				});

		// This event fires from BookmarksPanel.java
		AppUtils.EVENT_BUS.addHandler(BookmarkClickEvent.TYPE,
				new BookmarkClickEventHandler() {

					@Override
					public void onBookmarkBtnClick(
							BookmarkClickEvent bookmarkClickEvent) {
						if (reloadBookmarks) {
							bookmarksPanel.rebuildBookmarksPanel();
							reloadBookmarks = false;
						}
						adminPanel.setSelectedTab(0);
						scrollPanel.clear();
						scrollPanel.add(bookmarksPanel);
					}
				});

		// This event fires from BookmarksPanel.java.
		AppUtils.EVENT_BUS.addHandler(AdminClickEvent.TYPE,
				new AdminClickEventHandler() {

					@Override
					public void onAdminBtnClick(AdminClickEvent adminClickEvent) {
						scrollPanel.clear();
						scrollPanel.add(adminPanel);
					}
				});
	}

	private User_data parseUserData(String jsonData) {
		User_data user = null;
		JSONValue value = JSONParser.parseStrict(jsonData);
		JSONObject userObj = value.isObject();
		String result = userObj.get("result").isString().stringValue();
		if (result.equals("success")) {
			JSONArray userArray = userObj.get("user").isArray();
			if (userArray != null) {
				for (int i = 0; i < userArray.size(); i++) {
					JSONObject bookmarkObj = userArray.get(i).isObject();
					int idUser = Integer.parseInt(bookmarkObj.get("idUser")
							.isString().stringValue());
					String username = bookmarkObj.get("username").isString()
							.stringValue();
					String userFullName = bookmarkObj.get("userFullName")
							.isString().stringValue();
					String userEmail = bookmarkObj.get("userEmail").isString()
							.stringValue();
					String sessionID = bookmarkObj.get("SESSION_ID").isString()
							.stringValue();
					user = new User_data(idUser, username, userFullName,
							userEmail, sessionID);
				}
			} else
				return null;
		} else
			return null;
		return user;
	}
}
